package com.example.a_java.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.a_java.dto.LoanInspectionDTO;
import com.example.a_java.dto.LoanInspectionQuery;
import com.example.a_java.entity.LoanApply;
import com.example.a_java.entity.LoanContract;
import com.example.a_java.entity.LoanInspection;
import com.example.a_java.entity.LoanInspectionAttachment;
import com.example.a_java.mapper.LoanApplyMapper;
import com.example.a_java.mapper.LoanContractMapper;
import com.example.a_java.mapper.LoanInspectionAttachmentMapper;
import com.example.a_java.mapper.LoanInspectionMapper;
import com.example.a_java.service.LoanInspectionService;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

/**
 * 贷后检查服务实现类
 */
@Service
@RequiredArgsConstructor
public class LoanInspectionServiceImpl extends ServiceImpl<LoanInspectionMapper, LoanInspection> implements LoanInspectionService {

    private final LoanInspectionMapper loanInspectionMapper;
    private final LoanInspectionAttachmentMapper attachmentMapper;
    private final LoanApplyMapper loanApplyMapper;
    private final LoanContractMapper loanContractMapper;
    
    private static final String UPLOAD_DIR = "uploads/inspection/";

    @Override
    public Page<LoanInspection> getInspectionList(LoanInspectionQuery query) {
        Page<LoanInspection> page = new Page<>(query.getPageNum(), query.getPageSize());
        
        LambdaQueryWrapper<LoanInspection> wrapper = new LambdaQueryWrapper<>();
        
        // 添加查询条件
        if (StringUtils.isNotBlank(query.getLoanNo())) {
            wrapper.like(LoanInspection::getLoanNo, query.getLoanNo());
        }
        
        if (StringUtils.isNotBlank(query.getCustomerName())) {
            wrapper.like(LoanInspection::getCustomerName, query.getCustomerName());
        }
        
        if (StringUtils.isNotBlank(query.getStatus())) {
            wrapper.eq(LoanInspection::getStatus, query.getStatus());
        }
        
        // 日期范围查询
        if (StringUtils.isNotBlank(query.getStartDate())) {
            wrapper.ge(LoanInspection::getPlanDate, LocalDate.parse(query.getStartDate()));
        }
        
        if (StringUtils.isNotBlank(query.getEndDate())) {
            wrapper.le(LoanInspection::getPlanDate, LocalDate.parse(query.getEndDate()));
        }
        
        // 默认按计划日期降序排序
        wrapper.orderByDesc(LoanInspection::getPlanDate);
        
        return page(page, wrapper);
    }

    @Override
    public LoanInspection getInspectionDetail(Long id) {
        LoanInspection inspection = getById(id);
        if (inspection != null) {
            // 查询附件列表
            List<LoanInspectionAttachment> attachments = attachmentMapper.findByInspectionId(id);
            inspection.setAttachments(attachments);
        }
        return inspection;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long addInspection(LoanInspectionDTO dto) {
        LoanInspection inspection = new LoanInspection();
        BeanUtils.copyProperties(dto, inspection);
        
        // 设置日期
        if (StringUtils.isNotBlank(dto.getPlanDate())) {
            inspection.setPlanDate(LocalDate.parse(dto.getPlanDate()));
        }
        
        // 设置默认状态为待检
        inspection.setStatus("pending");
        
        // 查询贷款申请信息和合同信息，填充相关字段
        LoanApply loanApply = loanApplyMapper.selectByLoanNo(dto.getLoanNo());
        if (loanApply != null) {
            inspection.setCustomerName(loanApply.getCustomerName());
            inspection.setLoanAmount(loanApply.getLoanAmount());
            inspection.setLoanTerm(loanApply.getLoanTerm());
            inspection.setLoanPurpose(loanApply.getLoanPurpose());
            
            // 查询合同信息
            LambdaQueryWrapper<LoanContract> contractWrapper = new LambdaQueryWrapper<>();
            contractWrapper.eq(LoanContract::getApplyId, loanApply.getApplyId());
            LoanContract contract = loanContractMapper.selectOne(contractWrapper);
            if (contract != null) {
                inspection.setContractNo(contract.getContractNo());
            }
        }
        
        // 设置创建时间
        inspection.setCreateTime(LocalDateTime.now());
        
        // 保存检查记录
        save(inspection);
        
        return inspection.getId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean submitInspection(LoanInspectionDTO dto) {
        LoanInspection inspection = getById(dto.getId());
        if (inspection == null) {
            throw new RuntimeException("检查记录不存在");
        }
        
        // 更新基本信息
        BeanUtils.copyProperties(dto, inspection);
        
        // 设置日期
        if (StringUtils.isNotBlank(dto.getActualDate())) {
            inspection.setActualDate(LocalDate.parse(dto.getActualDate()));
        }
        
        // 设置状态为已完成
        inspection.setStatus("completed");
        
        // 设置更新时间
        inspection.setUpdateTime(LocalDateTime.now());
        
        // 更新检查记录
        boolean result = updateById(inspection);
        
        // 处理附件关联
        if (dto.getAttachmentIds() != null && !dto.getAttachmentIds().isEmpty()) {
            for (Long attachmentId : dto.getAttachmentIds()) {
                LoanInspectionAttachment attachment = attachmentMapper.selectById(attachmentId);
                if (attachment != null && attachment.getInspectionId() == null) {
                    attachment.setInspectionId(inspection.getId());
                    attachmentMapper.updateById(attachment);
                }
            }
        }
        
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Map<String, Object> uploadAttachment(MultipartFile file) throws IOException {
        if (file.isEmpty()) {
            throw new RuntimeException("上传文件不能为空");
        }
        
        // 创建上传目录
        String datePath = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));
        String uploadPath = UPLOAD_DIR + datePath;
        File uploadDir = new File(uploadPath);
        if (!uploadDir.exists()) {
            uploadDir.mkdirs();
        }
        
        // 生成文件名
        String originalFilename = file.getOriginalFilename();
        String extension = originalFilename.substring(originalFilename.lastIndexOf("."));
        String filename = UUID.randomUUID().toString() + extension;
        
        // 保存文件
        Path filePath = Paths.get(uploadPath, filename);
        Files.write(filePath, file.getBytes());
        
        // 保存附件信息
        LoanInspectionAttachment attachment = new LoanInspectionAttachment();
        attachment.setName(originalFilename);
        attachment.setUrl(uploadPath + "/" + filename);
        attachment.setSize(file.getSize());
        attachment.setType(file.getContentType());
        attachment.setUploadTime(LocalDateTime.now());
        attachment.setCreateTime(LocalDateTime.now());
        
        attachmentMapper.insert(attachment);
        
        // 返回附件信息
        Map<String, Object> result = new HashMap<>();
        result.put("id", attachment.getId());
        result.put("name", attachment.getName());
        result.put("url", attachment.getUrl());
        result.put("size", attachment.getSize());
        result.put("type", attachment.getType());
        result.put("uploadTime", attachment.getUploadTime());
        
        return result;
    }

    @Override
    public Map<String, Object> getAttachment(Long id) {
        LoanInspectionAttachment attachment = attachmentMapper.selectById(id);
        if (attachment == null) {
            throw new RuntimeException("附件不存在");
        }
        
        Map<String, Object> result = new HashMap<>();
        result.put("id", attachment.getId());
        result.put("name", attachment.getName());
        result.put("url", attachment.getUrl());
        result.put("size", attachment.getSize());
        result.put("type", attachment.getType());
        result.put("uploadTime", attachment.getUploadTime());
        
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteInspection(Long id) {
        // 先删除关联的附件
        LambdaQueryWrapper<LoanInspectionAttachment> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(LoanInspectionAttachment::getInspectionId, id);
        attachmentMapper.delete(wrapper);
        
        // 删除检查记录
        return removeById(id);
    }
} 
